#pragma once

#include "types.hpp"
#include <iostream>
#include <algorithm>
#include <vector>

extern std::ostream& operator<<(std::ostream& os, const position_t& p);

/// Coloring in terminal utilities (for only linux)
namespace TermColor
{
enum Fore
{
	Red,Green,Blue,
	Yellow, Magenta, Cyan,
	Black, White, Default, Size
};

namespace Back
{
	enum Back
	{
		Red,Green,Blue,
		Yellow, Magenta, Cyan,
		Black, Gray, Default, Size
	};

	extern std::ostream& operator<<(std::ostream& os, Back b);
}

extern std::ostream& operator<<(std::ostream& os, Fore f);
extern void DisableColoring();

template<class T>
class OneTimeColorist
{
	friend std::ostream& 
		operator<<(std::ostream& os, OneTimeColorist<T> c)
	{
		return os << c.f << c.b << c.o
			<< Default << Back::Default;
	}
	
	Fore f;
	Back::Back b;
	T& o;
	
public:
	OneTimeColorist(T& obj, Fore fore, Back::Back back)
		: f(fore), b(back), o(obj)
	{
	}
};

template<class T>
inline OneTimeColorist<T> OneTime(
	T& obj, Fore fore, Back::Back back = Back::Default)
{
	return OneTimeColorist<T>(obj, fore, back);
}
}

/**
* @brief Vector of pointer
*
* @tparam T Element Type
*/
template<class T>
class ptr_vector : public std::vector<T*>
{
	typedef std::vector<T*> base;
	
public:
	typedef typename base::iterator iterator;
	
public:
	~ptr_vector()
	{
		while(base::empty() == false)
		{
			delete base::back();
			base::pop_back();
		}
	}

	T& operator()(uint i) const
	{
		return *this->base::operator[](i);
	}

	void remove(T* ptr)
	{
		iterator i = std::find(base::begin(), base::end(), ptr);
		if(i != base::end())
			remove(i);
	}
	void remove(iterator& pos)
	{
		delete *pos;
		base::erase(pos);
	}
};

template<class T, class ParentType>
class CProperty
{
public:
	typedef ParentType Parent;
	typedef ptr_vector<T> Parent::*Container;
};

